/*     */ package com.zimbra.cs.account.accesscontrol;
/*     */ 
/*     */ import com.zimbra.common.account.Key.AccountBy;
/*     */ import com.zimbra.common.service.ServiceException;
/*     */ import com.zimbra.common.soap.Element;
/*     */ import com.zimbra.common.util.DateUtil;
/*     */ import com.zimbra.common.util.Log;
/*     */ import com.zimbra.common.util.ZimbraLog;
/*     */ import com.zimbra.cs.account.Account;
/*     */ import com.zimbra.cs.account.AttributeManager;
/*     */ import com.zimbra.cs.account.AttributeType;
/*     */ import com.zimbra.cs.account.Cos;
/*     */ import com.zimbra.cs.account.Domain;
/*     */ import com.zimbra.cs.account.Entry;
/*     */ import com.zimbra.cs.account.Provisioning;
/*     */ import com.zimbra.cs.account.Server;
/*     */ import com.zimbra.soap.admin.type.ConstraintInfo;
/*     */ import java.io.PrintStream;
/*     */ import java.util.ArrayList;
/*     */ import java.util.Date;
/*     */ import java.util.HashMap;
/*     */ import java.util.HashSet;
/*     */ import java.util.List;
/*     */ import java.util.Map;
/*     */ import java.util.Set;
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ public class AttributeConstraint
/*     */ {
/*     */   private static final String CONSTRAINT_CACHE_KEY = "CONSTRAINT_CACHE";
/*     */   private static final String PARTS_DELIMITER = ":";
/*     */   private static final String VALUES_DELIMITER = ",";
/*     */   private String mAttrName;
/*     */   private Set<String> mValues;
/*     */   
/*     */   AttributeConstraint(String attrName)
/*     */   {
/*  52 */     this.mAttrName = attrName;
/*     */   }
/*     */   
/*     */   private String getAttrName() {
/*  56 */     return this.mAttrName;
/*     */   }
/*     */   
/*     */   protected void setMin(String min) throws ServiceException {
/*  60 */     throw ServiceException.PARSE_ERROR("min constraint not supported for the attribute type", null);
/*     */   }
/*     */   
/*     */   protected void setMax(String max) throws ServiceException {
/*  64 */     throw ServiceException.PARSE_ERROR("max constraint not supported for attribute type", null);
/*     */   }
/*     */   
/*     */   private void addValue(String value) {
/*  68 */     if (this.mValues == null)
/*  69 */       this.mValues = new HashSet();
/*  70 */     this.mValues.add(value);
/*     */   }
/*     */   
/*     */   private boolean isEmpty() {
/*  74 */     return (getMin() == null) && (getMax() == null) && (getValues() == null);
/*     */   }
/*     */   
/*     */   private Set<String> getValues() {
/*  78 */     return this.mValues;
/*     */   }
/*     */   
/*     */   protected String getMin() {
/*  82 */     return null;
/*     */   }
/*     */   
/*     */   protected String getMax() {
/*  86 */     return null;
/*     */   }
/*     */   
/*     */   protected boolean violateMinMax(String value) throws ServiceException {
/*  90 */     return false;
/*     */   }
/*     */   
/*     */   private boolean violateValues(String value) {
/*  94 */     return (this.mValues != null) && (!this.mValues.contains(value));
/*     */   }
/*     */   
/*     */   protected boolean violated(Object value) throws ServiceException {
/*  98 */     if ((value instanceof String)) {
/*  99 */       if (violateValues((String)value))
/* 100 */         return true;
/* 101 */       if (violateMinMax((String)value)) {
/* 102 */         return true;
/*     */       }
/* 104 */     } else if ((value instanceof String[])) {
/* 105 */       for (String v : (String[])value) {
/* 106 */         if (violateValues(v))
/* 107 */           return true;
/* 108 */         if (violateMinMax(v))
/* 109 */           return true;
/*     */       }
/*     */     } else {
/* 112 */       throw ServiceException.FAILURE("internal error", null);
/*     */     }
/*     */     
/* 115 */     return false;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   private static class IntegerConstraint
/*     */     extends AttributeConstraint
/*     */   {
/*     */     private Integer mMin;
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     private Integer mMax;
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */     IntegerConstraint(String attrName)
/*     */     {
/* 145 */       super();
/*     */     }
/*     */     
/*     */     protected void setMin(String min)
/*     */     {
/*     */       try {
/* 151 */         this.mMin = Integer.valueOf(min);
/*     */       }
/*     */       catch (NumberFormatException e) {}
/*     */     }
/*     */     
/*     */     protected void setMax(String max)
/*     */     {
/*     */       try
/*     */       {
/* 160 */         this.mMax = Integer.valueOf(max);
/*     */       }
/*     */       catch (NumberFormatException e) {}
/*     */     }
/*     */     
/*     */ 
/*     */     protected String getMin()
/*     */     {
/* 168 */       return this.mMin == null ? null : this.mMin.toString();
/*     */     }
/*     */     
/*     */     protected String getMax()
/*     */     {
/* 173 */       return this.mMax == null ? null : this.mMax.toString();
/*     */     }
/*     */     
/*     */     protected boolean violateMinMax(String valueStr) throws ServiceException
/*     */     {
/*     */       try {
/* 179 */         Integer value = Integer.valueOf(valueStr);
/* 180 */         if ((this.mMin != null) && (value.intValue() < this.mMin.intValue())) {
/* 181 */           return true;
/*     */         }
/* 183 */         if ((this.mMax != null) && (value.intValue() > this.mMax.intValue()))
/* 184 */           return true;
/*     */       } catch (NumberFormatException e) {
/* 186 */         return true;
/*     */       }
/* 188 */       return false;
/*     */     }
/*     */   }
/*     */   
/*     */   private static class LongConstraint extends AttributeConstraint {
/*     */     private Long mMin;
/*     */     private Long mMax;
/*     */     
/*     */     LongConstraint(String attrName) {
/* 197 */       super();
/*     */     }
/*     */     
/*     */     protected void setMin(String min)
/*     */     {
/*     */       try {
/* 203 */         this.mMin = Long.valueOf(min);
/*     */       }
/*     */       catch (NumberFormatException e) {}
/*     */     }
/*     */     
/*     */     protected void setMax(String max)
/*     */     {
/*     */       try
/*     */       {
/* 212 */         this.mMax = Long.valueOf(max);
/*     */       }
/*     */       catch (NumberFormatException e) {}
/*     */     }
/*     */     
/*     */ 
/*     */     protected String getMin()
/*     */     {
/* 220 */       return this.mMin == null ? null : this.mMin.toString();
/*     */     }
/*     */     
/*     */     protected String getMax()
/*     */     {
/* 225 */       return this.mMax == null ? null : this.mMax.toString();
/*     */     }
/*     */     
/*     */     protected boolean violateMinMax(String valueStr) throws ServiceException
/*     */     {
/*     */       try {
/* 231 */         Long value = Long.valueOf(valueStr);
/* 232 */         if ((this.mMin != null) && (value.longValue() < this.mMin.longValue())) {
/* 233 */           return true;
/*     */         }
/* 235 */         if ((this.mMax != null) && (value.longValue() > this.mMax.longValue()))
/* 236 */           return true;
/*     */       } catch (NumberFormatException e) {
/* 238 */         return true;
/*     */       }
/* 240 */       return false;
/*     */     }
/*     */   }
/*     */   
/*     */   private static class DurationConstraint extends AttributeConstraint {
/*     */     private Long mMin;
/*     */     private Long mMax;
/*     */     
/*     */     DurationConstraint(String attrName) {
/* 249 */       super();
/*     */     }
/*     */     
/*     */     protected void setMin(String min)
/*     */     {
/*     */       try {
/* 255 */         this.mMin = Long.valueOf(DateUtil.getTimeInterval(min));
/*     */       }
/*     */       catch (ServiceException e) {}
/*     */     }
/*     */     
/*     */     protected void setMax(String max)
/*     */     {
/*     */       try
/*     */       {
/* 264 */         this.mMax = Long.valueOf(DateUtil.getTimeInterval(max));
/*     */       }
/*     */       catch (ServiceException e) {}
/*     */     }
/*     */     
/*     */ 
/*     */     protected String getMin()
/*     */     {
/* 272 */       return this.mMin == null ? null : this.mMin.toString();
/*     */     }
/*     */     
/*     */     protected String getMax()
/*     */     {
/* 277 */       return this.mMax == null ? null : this.mMax.toString();
/*     */     }
/*     */     
/*     */     protected boolean violateMinMax(String valueStr) throws ServiceException
/*     */     {
/*     */       try {
/* 283 */         Long value = Long.valueOf(DateUtil.getTimeInterval(valueStr));
/* 284 */         if ((this.mMin != null) && (value.longValue() < this.mMin.longValue())) {
/* 285 */           return true;
/*     */         }
/* 287 */         if ((this.mMax != null) && (value.longValue() > this.mMax.longValue()))
/* 288 */           return true;
/*     */       } catch (ServiceException e) {
/* 290 */         return true;
/*     */       }
/* 292 */       return false;
/*     */     }
/*     */   }
/*     */   
/*     */   private static class GentimeConstraint extends AttributeConstraint
/*     */   {
/*     */     private Long mMin;
/*     */     private Long mMax;
/*     */     
/*     */     GentimeConstraint(String attrName) {
/* 302 */       super();
/*     */     }
/*     */     
/*     */ 
/*     */     protected void setMin(String min)
/*     */     {
/* 308 */       Date date = DateUtil.parseGeneralizedTime(min);
/* 309 */       if (date != null) {
/* 310 */         this.mMin = Long.valueOf(date.getTime());
/*     */       }
/*     */     }
/*     */     
/*     */     protected void setMax(String max)
/*     */     {
/* 316 */       Date date = DateUtil.parseGeneralizedTime(max);
/* 317 */       if (date != null) {
/* 318 */         this.mMax = Long.valueOf(date.getTime());
/*     */       }
/*     */     }
/*     */     
/*     */     protected String getMin() {
/* 323 */       return this.mMin == null ? null : this.mMin.toString();
/*     */     }
/*     */     
/*     */     protected String getMax()
/*     */     {
/* 328 */       return this.mMax == null ? null : this.mMax.toString();
/*     */     }
/*     */     
/*     */     protected boolean violateMinMax(String valueStr) throws ServiceException
/*     */     {
/* 333 */       Date value = DateUtil.parseGeneralizedTime(valueStr);
/* 334 */       if (value == null) {
/* 335 */         return true;
/*     */       }
/* 337 */       long mSecs = value.getTime();
/* 338 */       if ((this.mMin != null) && (mSecs < this.mMin.longValue())) {
/* 339 */         return true;
/*     */       }
/* 341 */       if ((this.mMax != null) && (mSecs > this.mMax.longValue())) {
/* 342 */         return true;
/*     */       }
/* 344 */       return false;
/*     */     }
/*     */   }
/*     */   
/*     */   public String toString() {
/* 349 */     StringBuilder sb = new StringBuilder();
/*     */     
/* 351 */     sb.append(getAttrName());
/*     */     
/* 353 */     String min = getMin();
/* 354 */     if (min != null) {
/* 355 */       sb.append(":min=" + min);
/*     */     }
/* 357 */     String max = getMax();
/* 358 */     if (max != null) {
/* 359 */       sb.append(":max=" + max);
/*     */     }
/* 361 */     Set<String> values = getValues();
/* 362 */     boolean first; if ((values != null) && (values.size() > 0)) {
/* 363 */       sb.append(":values=");
/* 364 */       first = true;
/* 365 */       for (String value : values) {
/* 366 */         if (!first) {
/* 367 */           sb.append(",");
/*     */         } else
/* 369 */           first = false;
/* 370 */         sb.append(value);
/*     */       }
/*     */     }
/*     */     
/* 374 */     return sb.toString();
/*     */   }
/*     */   
/*     */   private static AttributeConstraint fromString(AttributeManager am, String s) throws ServiceException {
/* 378 */     String[] parts = s.split(":");
/* 379 */     if (parts.length < 2) {
/* 380 */       throw ServiceException.PARSE_ERROR("invalid constraint: " + s, null);
/*     */     }
/* 382 */     String attrName = parts[0];
/* 383 */     AttributeConstraint constraint = newConstratint(am, attrName);
/*     */     
/* 385 */     for (int i = 1; i < parts.length; i++) {
/* 386 */       String part = parts[i];
/* 387 */       if (part.startsWith("min=")) {
/* 388 */         constraint.setMin(part.substring(4));
/* 389 */       } else if (part.startsWith("max=")) {
/* 390 */         constraint.setMax(part.substring(4));
/* 391 */       } else if (part.startsWith("values=")) {
/* 392 */         String values = part.substring(7);
/* 393 */         String[] vs = values.split(",");
/* 394 */         for (String v : vs) {
/* 395 */           constraint.addValue(v);
/*     */         }
/*     */       }
/*     */     }
/* 399 */     return constraint;
/*     */   }
/*     */   
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */   public static AttributeConstraint fromJaxb(AttributeManager am, String attrName, ConstraintInfo eConstraint)
/*     */     throws ServiceException
/*     */   {
/* 411 */     if (eConstraint == null)
/* 412 */       return null;
/* 413 */     AttributeConstraint constraint = newConstratint(am, attrName);
/*     */     
/* 415 */     constraint.setMin(eConstraint.getMin());
/* 416 */     constraint.setMax(eConstraint.getMax());
/* 417 */     for (String value : eConstraint.getValues())
/* 418 */       constraint.addValue(value);
/* 419 */     return constraint;
/*     */   }
/*     */   
/*     */   public static AttributeConstraint fromXML(AttributeManager am, String attrName, Element eConstraint) throws ServiceException
/*     */   {
/* 424 */     AttributeConstraint constraint = newConstratint(am, attrName);
/*     */     
/* 426 */     Element eMin = eConstraint.getOptionalElement("min");
/* 427 */     if (eMin != null) {
/* 428 */       constraint.setMin(eMin.getText());
/*     */     }
/* 430 */     Element eMax = eConstraint.getOptionalElement("max");
/* 431 */     if (eMax != null) {
/* 432 */       constraint.setMax(eMax.getText());
/*     */     }
/* 434 */     Element eValues = eConstraint.getOptionalElement("values");
/* 435 */     if (eValues != null) {
/* 436 */       for (Element eValue : eValues.listElements("v")) {
/* 437 */         constraint.addValue(eValue.getText());
/*     */       }
/*     */     }
/* 440 */     return constraint;
/*     */   }
/*     */   
/*     */   public void toXML(Element eParent) {
/* 444 */     Element eConstraint = eParent.addElement("constraint");
/*     */     
/* 446 */     String min = getMin();
/* 447 */     if (min != null) {
/* 448 */       eConstraint.addElement("min").setText(min);
/*     */     }
/* 450 */     String max = getMax();
/* 451 */     if (max != null) {
/* 452 */       eConstraint.addElement("max").setText(max);
/*     */     }
/* 454 */     Set<String> values = getValues();
/* 455 */     Element eValues; if (values != null) {
/* 456 */       eValues = eConstraint.addElement("values");
/* 457 */       for (String v : values)
/* 458 */         eValues.addElement("v").setText(v);
/*     */     }
/*     */   }
/*     */   
/*     */   static AttributeConstraint newConstratint(AttributeManager am, String attrName) throws ServiceException {
/* 463 */     AttributeType at = am.getAttributeType(attrName);
/*     */     
/* 465 */     switch (at) {
/*     */     case TYPE_BOOLEAN: 
/* 467 */       return new AttributeConstraint(attrName);
/*     */     case TYPE_DURATION: 
/* 469 */       return new DurationConstraint(attrName);
/*     */     case TYPE_GENTIME: 
/* 471 */       return new GentimeConstraint(attrName);
/*     */     case TYPE_EMAIL: 
/*     */     case TYPE_EMAILP: 
/*     */     case TYPE_CS_EMAILP: 
/*     */     case TYPE_ENUM: 
/*     */     case TYPE_ID: 
/* 477 */       return new AttributeConstraint(attrName);
/*     */     case TYPE_INTEGER: 
/* 479 */       return new IntegerConstraint(attrName);
/*     */     case TYPE_PORT: 
/* 481 */       return new IntegerConstraint(attrName);
/*     */     case TYPE_PHONE: 
/*     */     case TYPE_STRING: 
/*     */     case TYPE_ASTRING: 
/*     */     case TYPE_OSTRING: 
/*     */     case TYPE_CSTRING: 
/*     */     case TYPE_REGEX: 
/*     */     case TYPE_BINARY: 
/*     */     case TYPE_CERTIFICATE: 
/* 490 */       return new AttributeConstraint(attrName);
/*     */     case TYPE_LONG: 
/* 492 */       return new LongConstraint(attrName);
/*     */     }
/*     */     
/* 495 */     throw ServiceException.FAILURE("internal error", null);
/*     */   }
/*     */   
/*     */   static Entry getConstraintEntry(Entry entry) throws ServiceException {
/* 499 */     Provisioning prov = Provisioning.getInstance();
/* 500 */     Entry constraintEntry = null;
/*     */     
/* 502 */     if ((entry instanceof Account)) {
/* 503 */       constraintEntry = prov.getCOS((Account)entry);
/* 504 */     } else if (((entry instanceof Domain)) || ((entry instanceof Server))) {
/* 505 */       constraintEntry = prov.getConfig();
/*     */     }
/* 507 */     return constraintEntry;
/*     */   }
/*     */   
/*     */   public static Map<String, AttributeConstraint> getConstraint(Entry constraintEntry) throws ServiceException
/*     */   {
/* 512 */     Map<String, AttributeConstraint> constraints = (Map)constraintEntry.getCachedData("CONSTRAINT_CACHE");
/* 513 */     if (constraints == null)
/*     */     {
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 520 */       constraints = loadConstraints(constraintEntry);
/* 521 */       constraintEntry.setCachedData("CONSTRAINT_CACHE", constraints);
/*     */     }
/*     */     
/* 524 */     return constraints;
/*     */   }
/*     */   
/*     */   private static Map<String, AttributeConstraint> loadConstraints(Entry constraintEntry) throws ServiceException {
/* 528 */     Map<String, AttributeConstraint> constraints = new HashMap();
/*     */     
/* 530 */     Set<String> cstrnts = constraintEntry.getMultiAttrSet("zimbraConstraint");
/*     */     
/* 532 */     AttributeManager am = AttributeManager.getInstance();
/* 533 */     for (String c : cstrnts) {
/* 534 */       AttributeConstraint constraint = fromString(am, c);
/* 535 */       constraints.put(constraint.getAttrName(), constraint);
/*     */     }
/*     */     
/* 538 */     return constraints;
/*     */   }
/*     */   
/*     */   public static void modifyConstraint(Entry constraintEntry, List<AttributeConstraint> newConstraints)
/*     */     throws ServiceException
/*     */   {
/* 544 */     Map<String, AttributeConstraint> curConstraints = loadConstraints(constraintEntry);
/*     */     
/* 546 */     for (AttributeConstraint newConstraintsForAttr : newConstraints) {
/* 547 */       String attrName = newConstraintsForAttr.getAttrName();
/* 548 */       AttributeConstraint curConstraintsForAttr = (AttributeConstraint)curConstraints.get(attrName);
/*     */       
/* 550 */       if (curConstraintsForAttr != null)
/*     */       {
/* 552 */         if (newConstraintsForAttr.isEmpty())
/*     */         {
/* 554 */           curConstraints.remove(attrName);
/*     */         }
/*     */         else {
/* 557 */           curConstraints.put(attrName, newConstraintsForAttr);
/*     */         }
/*     */         
/*     */ 
/*     */       }
/* 562 */       else if (!newConstraintsForAttr.isEmpty()) {
/* 563 */         curConstraints.put(attrName, newConstraintsForAttr);
/*     */       }
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 571 */     Map<String, Object> newAttrValues = new HashMap();
/* 572 */     if (curConstraints.size() == 0) {
/* 573 */       newAttrValues.put("zimbraConstraint", null);
/*     */     } else {
/* 575 */       List<String> newValues = new ArrayList();
/* 576 */       for (AttributeConstraint at : curConstraints.values()) {
/* 577 */         newValues.add(at.toString());
/*     */       }
/*     */       
/* 580 */       newAttrValues.put("zimbraConstraint", newValues.toArray(new String[newValues.size()]));
/*     */     }
/* 582 */     Provisioning.getInstance().modifyAttrs(constraintEntry, newAttrValues);
/*     */   }
/*     */   
/*     */   private static boolean ignoreConstraint(String attrName) {
/* 586 */     return ("zimbraCOSId".equals(attrName)) || ("zimbraDomainDefaultCOSId".equals(attrName));
/*     */   }
/*     */   
/*     */   static boolean violateConstraint(Map<String, AttributeConstraint> constraints, String attrName, Object value) throws ServiceException
/*     */   {
/* 591 */     AttributeConstraint constraint = (AttributeConstraint)constraints.get(attrName);
/* 592 */     if (constraint == null) {
/* 593 */       return false;
/*     */     }
/* 595 */     if (ignoreConstraint(attrName)) {
/* 596 */       ZimbraLog.acl.warn("Constraint for " + attrName + " is not suported and is ignored.");
/* 597 */       return false;
/*     */     }
/*     */     
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/*     */ 
/* 605 */     boolean violated = constraint.violated(value);
/* 606 */     if (violated)
/* 607 */       throw ServiceException.PERM_DENIED("constraint violated: " + constraint.getAttrName());
/* 608 */     return violated;
/*     */   }
/*     */   
/*     */   private static void test(Map<String, AttributeConstraint> constraints, String attrName, Object value, boolean expected) throws ServiceException {
/* 612 */     boolean violated = false;
/*     */     try {
/* 614 */       violated = violateConstraint(constraints, attrName, value);
/*     */     } catch (ServiceException e) {
/* 616 */       if ("service.PERM_DENIED".equals(e.getCode())) {
/* 617 */         violated = true;
/*     */       } else {
/* 619 */         throw e;
/*     */       }
/*     */     }
/* 622 */     StringBuilder sb = new StringBuilder();
/* 623 */     if ((value instanceof String[])) {
/* 624 */       for (String s : (String[])value)
/* 625 */         sb.append(s + " ");
/*     */     } else {
/* 627 */       sb.append(value.toString());
/*     */     }
/*     */     
/* 630 */     System.out.println("Setting " + attrName + " to " + "[" + sb.toString() + "]" + " => " + (violated ? "denied" : "allowed"));
/* 631 */     if (violated != expected) {
/* 632 */       System.out.println("failed\n");
/*     */     }
/*     */   }
/*     */   
/*     */   public static void main(String[] args) throws ServiceException
/*     */   {
/* 638 */     Provisioning prov = Provisioning.getInstance();
/* 639 */     AttributeManager am = AttributeManager.getInstance();
/*     */     
/* 641 */     fromString(am, "zimbraPasswordMinLength:min=6");
/* 642 */     fromString(am, "zimbraPasswordMaxLength:min=64");
/* 643 */     fromString(am, "zimbraPasswordMinLength:min=6:max=64:values=1,2,3");
/* 644 */     fromString(am, "zimbraFeatureMailEnabled:values=FALSE,TRUE");
/*     */     
/* 646 */     Account acct = prov.get(Key.AccountBy.name, "user1@phoebe.mac");
/* 647 */     Cos cos = prov.getCOS(acct);
/* 648 */     cos.unsetConstraint();
/*     */     
/* 650 */     Map<String, Object> cosConstraints = new HashMap();
/*     */     
/*     */ 
/* 653 */     cos.addConstraint("zimbraPasswordMinLength:min=6:max=10:values=8,9", cosConstraints);
/*     */     
/*     */ 
/* 656 */     long longMax = Long.MAX_VALUE;
/* 657 */     long longMaxMinusOne = longMax - 1L;
/* 658 */     cos.addConstraint("zimbraMailQuota:max=" + longMaxMinusOne, cosConstraints);
/*     */     
/*     */ 
/* 661 */     cos.addConstraint("zimbraPasswordLockoutDuration:min=5h:max=1d", cosConstraints);
/*     */     
/*     */ 
/* 664 */     cos.addConstraint("zimbraPrefPop3DownloadSince:min=20060315023000Z", cosConstraints);
/*     */     
/*     */ 
/* 667 */     cos.addConstraint("zimbraPrefGroupMailBy:values=conversation", cosConstraints);
/*     */     
/*     */ 
/* 670 */     cos.addConstraint("zimbraCalendarMaxRevisions:min=zz:max=10", cosConstraints);
/*     */     
/*     */ 
/* 673 */     cos.addConstraint("zimbraZimletAvailableZimlets:values=A,B,C", cosConstraints);
/*     */     
/*     */ 
/* 676 */     prov.modifyAttrs(cos, cosConstraints);
/*     */     
/* 678 */     Map<String, AttributeConstraint> constraints = getConstraint(cos);
/*     */     
/* 680 */     test(constraints, "zimbraPasswordMinLength", "5", true);
/* 681 */     test(constraints, "zimbraPasswordMinLength", "6", true);
/* 682 */     test(constraints, "zimbraPasswordMinLength", "7", true);
/* 683 */     test(constraints, "zimbraPasswordMinLength", "8", false);
/* 684 */     test(constraints, "zimbraPasswordMinLength", "9", false);
/* 685 */     test(constraints, "zimbraPasswordMinLength", "10", true);
/* 686 */     test(constraints, "zimbraPasswordMinLength", "11", true);
/*     */     
/*     */ 
/* 689 */     test(constraints, "zimbraMailQuota", "" + longMaxMinusOne, false);
/* 690 */     test(constraints, "zimbraMailQuota", "" + longMax, true);
/*     */     
/*     */ 
/* 693 */     test(constraints, "zimbraPasswordLockoutDuration", "3h", true);
/* 694 */     test(constraints, "zimbraPasswordLockoutDuration", "25h", true);
/* 695 */     test(constraints, "zimbraPasswordLockoutDuration", "30m", true);
/* 696 */     test(constraints, "zimbraPasswordLockoutDuration", "5h", false);
/* 697 */     test(constraints, "zimbraPasswordLockoutDuration", "600m", false);
/* 698 */     test(constraints, "zimbraPasswordLockoutDuration", "24h", false);
/*     */     
/*     */ 
/* 701 */     test(constraints, "zimbraPrefPop3DownloadSince", "20050315023000Z", true);
/* 702 */     test(constraints, "zimbraPrefPop3DownloadSince", "20060315023000Z", false);
/* 703 */     test(constraints, "zimbraPrefPop3DownloadSince", "20060315023001Z", false);
/*     */     
/*     */ 
/* 706 */     test(constraints, "zimbraPrefGroupMailBy", "message", true);
/* 707 */     test(constraints, "zimbraPrefGroupMailBy", "conversation", false);
/*     */     
/*     */ 
/* 710 */     test(constraints, "zimbraCalendarMaxRevisions", "1", false);
/* 711 */     test(constraints, "zimbraCalendarMaxRevisions", "10", false);
/* 712 */     test(constraints, "zimbraCalendarMaxRevisions", "11", true);
/*     */     
/*     */ 
/* 715 */     test(constraints, "zimbraZimletAvailableZimlets", new String[] { "A", "B" }, false);
/* 716 */     test(constraints, "zimbraZimletAvailableZimlets", new String[] { "A", "X" }, true);
/*     */     
/* 718 */     test(constraints, "zimbraPasswordMaxLength", "100", false);
/*     */   }
/*     */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/account/accesscontrol/AttributeConstraint.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */